#include <sys/types.h>
#include <semaphore.h>
#include <mqueue.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#include "msg.h"

#define RQUEUE_MQ_NAME "/rqueue.msg"
#define RQUEUE_MQ_ILOCK "rqmsg.ilock"
#define RQUEUE_MQ_OLOCK "rqmsg.olock"

#define MAX_MSG 256

static mqd_t mqd;
static sem_t *mqisem = NULL;
static sem_t *mqosem = NULL;

static int msg_exit = 0;

int msg_init()
{
	mqd = mq_open(RQUEUE_MQ_NAME, O_CREAT|O_RDWR, 0644, NULL);
	if(mqd == -1)
	{
		perror("mq_open");
		return -1;
	}

	mqisem = sem_open(RQUEUE_MQ_ILOCK, O_CREAT|O_RDWR, 0644, 0);
	if(mqisem == SEM_FAILED)
	{
		perror("sem_open");
		return -1;
	}

	mqosem = sem_open(RQUEUE_MQ_OLOCK, O_CREAT|O_RDWR, 0644, 0);
	if(mqosem == SEM_FAILED)
	{
		perror("sem_open");
		return -1;
	}

	return 1;
}

int msg_fini()
{
	msg_exit = 1;
	sem_post(mqisem);

	if(-1 == mq_close(mqd)) return -1;

	if(-1 == mq_unlink(RQUEUE_MQ_NAME)) return -1;

	return   sem_close(mqisem) &
		 sem_unlink(RQUEUE_MQ_ILOCK) &
		 sem_close(mqosem) &
		 sem_unlink(RQUEUE_MQ_OLOCK);
}

int rq_msg_handler(const void* data, int length)
{
	struct mq_attr mqstat;
	if(-1 == mq_getattr(mqd, &mqstat)) return -1;

	if(MAX_MSG < mqstat.mq_curmsgs)
	{
		sem_wait(mqisem);
	}

	if(msg_exit == 1) return 0;

	if(-1 == mq_send(mqd, data, length, 0))


	if(mqstat.mq_curmsgs == 0)
	{
		sem_post(mqosem);
	}

	return 1;
}
